package com.ruoyi.quartz.util;

import java.io.BufferedReader;
import java.io.Reader;
import java.sql.Clob;
import java.sql.SQLException;

import javax.sql.rowset.serial.SerialException;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import lombok.extern.slf4j.Slf4j;


/**
 * @author pengjun
 * @ClassName: DataUtil
 * @Description: 数据处理工具类
 * @date 2019年1月8日
 */
@Slf4j
public class DataUtil {


    private DataUtil() {
        //no instance
    }

    public static void main(String[] args) {
        System.out.println(decodeUnicode("\\u963f\\u65af\\u8fbe"));
        System.out.println(unicodeToCn("\\u963f\\u65af\\u8fbe"));
        System.out.println(cnToUnicode("阿斯达"));
        System.out.println(htmlEncode("工@v&%"));
    }

    /**
     * @param cn
     * @return String    返回类型
     * @Title: cnToUnicode
     * @Description: 中文转unicode
     */
    private static String cnToUnicode(String cn) {
        char[] chars = cn.toCharArray();
        StringBuilder returnStr = new StringBuilder();
        for (int i = 0; i < chars.length; i++) {
            returnStr.append("\\u").append(Integer.toString(chars[i], 16));
        }
        return returnStr.toString();
    }

    /**
     * @param unicode
     * @return String    返回类型
     * @Title: unicodeToCn
     * @Description: unicode 转换成 中文
     */
    private static String unicodeToCn(String unicode) {
        /** 以 \ u 分割，因为java注释也能识别unicode，因此中间加了一个空格*/
        String[] strs = unicode.split("\\\\u");
        StringBuilder returnStr = new StringBuilder();
        // 由于unicode字符串以 \ u 开头，因此分割出的第一个字符是""。
        for (int i = 1; i < strs.length; i++) {
            returnStr.append((char) Integer.valueOf(strs[i], 16).intValue());
        }
        return returnStr.toString();
    }

    /**
     * @param theString
     * @param 参数
     * @return String    返回类型
     * @Title: decodeUnicode
     * @Description: unicode 转换成 中文
     */
    public static String decodeUnicode(String theString) {
        char aChar;
        int len = theString.length();
        StringBuffer outBuffer = new StringBuffer(len);
        for (int x = 0; x < len; ) {
            aChar = theString.charAt(x++);
            if (aChar == '\\') {
                aChar = theString.charAt(x++);
                if (aChar == 'u') {
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = theString.charAt(x++);
                        switch (aChar) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                value = (value << 4) + aChar - '0';
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                value = (value << 4) + 10 + aChar - 'a';
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                value = (value << 4) + 10 + aChar - 'A';
                                break;
                            default:
                                throw new IllegalArgumentException(
                                        "Malformed      encoding.");
                        }
                    }
                    outBuffer.append((char) value);
                } else {
                    if (aChar == 't') {
                        aChar = '\t';
                    } else if (aChar == 'r') {
                        aChar = '\r';
                    } else if (aChar == 'n') {
                        aChar = '\n';
                    } else if (aChar == 'f') {
                        aChar = '\f';
                    }
                    outBuffer.append(aChar);
                }
            } else {
                outBuffer.append(aChar);
            }
        }
        return outBuffer.toString();
    }

    /**
     * @param clob
     * @return String    返回类型
     * @Title: clobToString
     * @Description: clob字段转String类型
     */
    public static String clobToString(Clob clob) {
        Reader reader;
        StringBuffer sb = new StringBuffer();
        try {
            reader = clob.getCharacterStream();
            BufferedReader br = new BufferedReader(reader);
            String temp = null;
            while ((temp = br.readLine()) != null) {
                sb.append(temp);
            }
        } catch (Exception e) {
            log.error("ClobToString错误：", e);
        }
        return sb.toString();
    }

    /**
     * @param string
     * @return Clob    返回类型
     * @throws Exception 参数
     * @throws Exception
     * @Title: stringToClob
     * @Description: String类型转变Clob
     */
    public static Clob stringToClob(String string) throws Exception {
        Clob clob = null;
        try {
            clob = new javax.sql.rowset.serial.SerialClob(string.toCharArray());
        } catch (SerialException e) {
            log.error("StringToClob SerialException错误：", e);
        } catch (SQLException e) {
            log.error("StringToClob SQLException错误：", e);
        }
        return clob;
    }

    /**
     * @param str
     * @return String    返回类型
     * @Title: htmlEncode
     * @Description: 对传入的字符串str进行Html encode转换
     */
    public static String htmlEncode(String str) {
        if (str == null || str.trim().equals("")) {
            return str;
        }
        StringBuilder encodeStrBuilder = new StringBuilder();
        for (int i = 0, len = str.length(); i < len; i++) {
            encodeStrBuilder.append(htmlEncode(str.charAt(i)));
        }
        return encodeStrBuilder.toString();

    }

    private static String htmlEncode(char c) {
        switch (c) {
            case '&':
                return "&amp;";
            case '<':
                return "&lt;";
            case '>':
                return "&gt;";
            case '"':
                return "&quot;";
            case ' ':
                return "&nbsp;";
            default:
                return c + "";
        }

    }

    /**
     * 获取事务状态
     *
     * @param readOnly 是否只读事务
     * @return
     */
    public static TransactionStatus getTransactionStatus(boolean readOnly, DataSourceTransactionManager transactionManager) {
        DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        transactionDefinition.setReadOnly(readOnly);
        TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
        return transactionStatus;
    }

}
